package com.cn.wanxi.service.impl;

import com.cn.wanxi.common.ParseTool;
import com.cn.wanxi.common.RedisNumTool;
import com.cn.wanxi.common.ThreadTool;
import com.cn.wanxi.entity.NewsTypeEntity;
import com.cn.wanxi.entity.ResultEntity;
import com.cn.wanxi.mapper.NewsTypeMapper;
import com.cn.wanxi.service.INewsTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import java.util.ArrayList;
import java.util.List;

@Service
public class NewsTypeServiceImpl implements INewsTypeService {
    @Autowired
    private NewsTypeMapper newsTypeMapper;

    @Override
    public ResultEntity add(NewsTypeEntity newsTypeEntity) {
        int result = newsTypeMapper.add(newsTypeEntity);
        resetCache(result, 0);
        return ResultEntity.success(result);
    }

    @Override
    public ResultEntity update(NewsTypeEntity newsTypeEntity) {
        int result = newsTypeMapper.update(newsTypeEntity);
        resetCache(result, newsTypeEntity.getId());
        return ResultEntity.success(result);
    }

    @Override
    public ResultEntity delete(NewsTypeEntity newsTypeEntity) {
        int result = newsTypeMapper.delete(newsTypeEntity);
        resetCache(result, newsTypeEntity.getId());
        return ResultEntity.success(result);
    }

    @Override
    public List<NewsTypeEntity> findAll(NewsTypeEntity newsTypeEntity) {
        final List<NewsTypeEntity>[] list = new List[]{new ArrayList<>()};
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                list[0] = findAllCache(newsTypeEntity);
            }
        });
        thread.start();
        ThreadTool.ThreadSleep(thread);
        return list[0];
    }

    @Override
    public ResultEntity<NewsTypeEntity> findById(NewsTypeEntity newsTypeEntity) {
        final NewsTypeEntity[] model = {new NewsTypeEntity()};
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                model[0] = findByIdCache(newsTypeEntity);
            }
        });
        thread.start();
        ThreadTool.ThreadSleep(thread);
        return ResultEntity.success(model[0]);
    }

    @Override
    public Integer getCount(NewsTypeEntity newsTypeEntity) {
        final int[] result = {-1};
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                result[0] = findCountCache(newsTypeEntity);
            }
        });
        thread.start();
        ThreadTool.ThreadSleep(thread);
        return result[0];
    }

    /**
     * 查找所有新闻种类缓存
     *
     * @param newsTypeModel
     * @return
     */
    private synchronized List<NewsTypeEntity> findAllCache(NewsTypeEntity newsTypeModel) {
        List<NewsTypeEntity> list = new ArrayList<>();
        Jedis jedis = new Jedis();
        jedis.select(RedisNumTool.REDIS_TYPE_NEWS);
        boolean cache = jedis.exists("newsTypeModelId") && judgeModel(newsTypeModel);
        if (cache) {
            Long length = jedis.llen("newsTypeModelId");
            for (int i = 0; i < length; i++) {
                NewsTypeEntity model = new NewsTypeEntity();
                model.setId(ParseTool.StringToInt(jedis.lindex("newsTypeModelId", i)));
                model.setName(jedis.lindex("newsTypeModelName", i));
                model.setSort(ParseTool.StringToInt(jedis.lindex("newsTypeModelSort", i)));
                model.setEnable(ParseTool.StringToInt(jedis.lindex("newsTypeModelEnable", i)));
                list.add(model);
            }
        } else {
            list = newsTypeMapper.findAll(newsTypeModel);
            if (judgeModel(newsTypeModel)) {
                for (NewsTypeEntity model :
                        list) {
                    jedis.rpush("newsTypeModelId", String.valueOf(model.getId()));
                    jedis.rpush("newsTypeModelName", model.getName());
                    jedis.rpush("newsTypeModelSort", String.valueOf(model.getSort()));
                    jedis.rpush("newsTypeModelEnable", String.valueOf(model.getEnable()));
                }
            }
        }
        return list;
    }

    /**
     * 根据新闻种类id查找单个新闻种类缓存
     *
     * @param newsTypeModel
     * @return
     */
    private synchronized NewsTypeEntity findByIdCache(NewsTypeEntity newsTypeModel) {
        NewsTypeEntity model = new NewsTypeEntity();
        Jedis jedis = new Jedis();
        jedis.select(RedisNumTool.REDIS_TYPE_NEWS);
        String cacheName = "newsTypeModel_id_" + newsTypeModel.getId();
        boolean cache = jedis.exists(cacheName);
        if (cache) {
            model.setId(ParseTool.StringToInt(jedis.hget(cacheName, "id")));
            model.setName(jedis.hget(cacheName, "name"));
            model.setSort(ParseTool.StringToInt(jedis.hget(cacheName, "sort")));
            model.setEnable(ParseTool.StringToInt(jedis.hget(cacheName, "enable")));
        } else {
            model = newsTypeMapper.findById(newsTypeModel);
            jedis.hset(cacheName, "id", String.valueOf(model.getId()));
            jedis.hset(cacheName, "name", model.getName());
            jedis.hset(cacheName, "sort", String.valueOf(model.getSort()));
            jedis.hset(cacheName, "enable", String.valueOf(model.getEnable()));
        }
        return model;
    }

    /**
     * 获取新闻种类总数缓存
     *
     * @param newsTypeModel
     * @return
     */
    private synchronized int findCountCache(NewsTypeEntity newsTypeModel) {
        int result = -1;
        Jedis jedis = new Jedis();
        jedis.select(RedisNumTool.REDIS_TYPE_NEWS);
        boolean cache = jedis.exists("newsTypeModelCount") && judgeModel(newsTypeModel);
        if (cache) {
            result = ParseTool.StringToInt(jedis.get("newsTypeModelCount"));
        } else {
            result = newsTypeMapper.getCount(newsTypeModel);
            if (judgeModel(newsTypeModel)) {
                jedis.set("newsTypeModelCount", String.valueOf(result));
            }
        }
        return result;
    }


    /**
     * 更新后删除Redis中的缓存
     *
     * @param result
     */
    private void resetCache(int result, int id) {
        if (result > 0) {
            Jedis jedis = new Jedis();
            jedis.select(RedisNumTool.REDIS_TYPE_NEWS);
            jedis.del("newsTypeModelId", "newsTypeModelName", "newsTypeModelSort", "newsTypeModelEnable");
            jedis.del("newsTypeModelCount");
            jedis.del("newsTypeModel_id_" + id);
        }
    }

    /**
     * 判断model内是否有值
     * 没有值返回true
     *
     * @param model
     * @return
     */
    private boolean judgeModel(NewsTypeEntity model) {
        return model.getId() == null &&
                model.getName() == null &&
                model.getSort() == null &&
                ParseTool.enableToInt(model.getEnable()) == 1 &&
                ParseTool.pageToInt(model.getPage()) == 1 &&
                ParseTool.limitToInt(model.getLimit()) == 10;
    }
}
